package com.xh.demo.commons.utils;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author wen
 * @apiNote JacksonUtil
 * @since 2021/12/11
 */
@Slf4j
public class JacksonUtil {

    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        // 对于空的对象转json的时候不抛出错误
        OBJECT_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        // 禁用遇到未知属性抛出异常
        OBJECT_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 反序列化时，忽略目标对象没有的属性
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE);
    }

    /**
     * 序列化对象（转json）
     */
    public static String serialize(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof String) {
            return obj.toString();
        }
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("json序列化出错：" + obj, e);
            return null;
        }
    }

    /**
     * 反序列化（json转为Bean）
     */
    public static <T> T parse(String json, Class<T> tClass) {
        if (StrUtil.isEmpty(json)) return null;
        try {
            return OBJECT_MAPPER.readValue(json, tClass);
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    /**
     * 反序列化（json转List）
     */
    public static <E> List<E> parseList(String json, Class<E> eClass) {
        return nativeRead(json, List.class, eClass);
    }

    /**
     * 反序列化（json转Map）
     */
    public static <K, V> Map<K, V> parseMap(String json, Class<K> kClass, Class<V> vClass) {
        return nativeRead(json, Map.class, kClass, vClass);
    }

    /**
     * 反序列化（json转LinkedHashMap）
     */
    public static <K, V> LinkedHashMap<K, V> parseLinkedHashMap(String json, Class<K> kClass, Class<V> vClass) {
        return nativeRead(json, LinkedHashMap.class, kClass, vClass);
    }

    /**
     * json转复杂对象
     */
    public static <T> T nativeRead(String json, TypeReference<T> type) {
        if (StrUtil.isEmpty(json)) return null;
        try {
            return OBJECT_MAPPER.readValue(json, type);
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    /**
     * json转对象
     *
     * @param json         json字符串
     * @param javaClazz    需要转换的java对象类型，
     *                     例如：List.class, ArrayList.class, Map.class, HashMap.class, LinkedHashMap.class
     * @param genericClazz 泛型类型
     * @return T
     */
    public static <T> T nativeRead(String json, Class<?> javaClazz, Class<?>... genericClazz) {
        if (StrUtil.isEmpty(json)) return null;
        try {
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(javaClazz, genericClazz);
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (Exception e) {
            log.error("json解析出错", e);
            return null;
        }
    }

}
